<template>
  <!-- 组件的一些按钮的事件在组件里面有固定的跳转，如果想自定义，那么就可以给组件传递自定义的函数 -->
  <van-popup v-model:show="showRight" position="right" :style="{ width: '100%', height: '100%' }">
    <!-- 我在写一个popup弹出层的时候，新增和编辑是一个全新的业务，为了符合公司的代码规范，一般规定我们每个文件最好300行以内，所以就不得不去封装一些组件，让后将公共的地方写到组件里面，不一样的地方通过 props属性 和emits函数 实现父子通信。也可以顺便简化代码 -->
    <!-- <cp-nav-bar :title="title" :a="rigthText" :leftfn="fn" :rightfn="onSubmit" /> -->
    <cp-nav-bar :title="title" :a="rigthText" :leftfn="fn" :rightfn="save" />
    <van-form ref="submitRef" @submit="onSubmit" class="patient-detail">
      <van-cell-group inset>
        <van-field
          v-model="formDetail.name"
          label="真实姓名"
          name="name"
          placeholder="请填写姓名"
          :rules="nameRules"
        />
        <van-field
          v-model="formDetail.idCard"
          label="身份证号"
          name="idCard"
          placeholder="请填写身份证号"
          :rules="idCardRules"
        />
        <!-- vue3有区别？ vue3废弃了 sync语法， v-model在vue3里面一个组件上也可以使用多次 -->
        <!-- <cp-radio-btn :gender="formDetail.gender" @updateGenderEvent="updateGenderEvent" /> -->
        <cp-radio-btn
          :list="[
            { id: 1, name: '男' },
            { id: 0, name: '女' }
          ]"
          v-model="formDetail.gender"
        />
        <div class="default-patient">
          <div class="van-field__label">默认就诊人</div>
          <!-- 我们的值是0 1， 页面上是否勾选是通过 true false -->
          <!-- 我们需要的是这个组件是  如果是勾选了 不是true而是1. 如果没有勾选 不是false 而是0 -->
          <!-- <van-checkbox v-model="formDetail.defaultFlag"></van-checkbox> -->
          <van-checkbox v-model="defaultFlagCom"></van-checkbox>
        </div>

        <!-- <van-button
          ref="submitRef"
          style="display: none"
          round
          block
          type="primary"
          native-type="submit"
        >
          提交
        </van-button> -->
      </van-cell-group>
    </van-form>

    <!-- 一般放在底部的按钮叫 action-bar -->
    <van-action-bar v-if="formDetail.id">
      <van-action-bar-button type="danger" text="删除" @click="onClickButton" />
      <!-- <van-button plain type="danger">删除</van-button> -->
    </van-action-bar>
  </van-popup>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import idCard from 'idcard'
import { showToast, showConfirmDialog } from 'vant'
import { addPatientRequest, updatePatientRequest, deletePatientRequest } from '@/services/patient'

const props = defineProps({
  currentItem: {
    type: Object,
    // 新增的时候没有传递这个参数，就用默认值空对象，编辑的使用会传递具体的对象
    default: () => ({})
  }
})

const submitRef = ref<any>(null)
const title = ref('添加患者')
const rigthText = ref('保存')

console.log('父组件传递值进来：', props.currentItem)
watch(
  () => props.currentItem,
  (newV) => {
    console.log('wathc监听：', newV)
    if (newV.id) {
      // 只要进入了这个if分支，就表示当前是编辑状态
      title.value = '编辑患者'
      rigthText.value = '更新'

      formDetail.value.name = newV.name
      formDetail.value.idCard = newV.idCard
      formDetail.value.defaultFlag = newV.defaultFlag
      formDetail.value.gender = newV.gender
      // 因为编辑接口需要使用id字段，然后我们页面是编辑还是新增也需要用id有没有值去判断
      // 所有给这个对象，添加一个新属性id
      formDetail.value.id = newV.id
    } else {
      title.value = '添加患者'
      rigthText.value = '保存'
      // 点了编辑 在点新增， 将数据重置， 这个时候id也没有了
      formDetail.value.name = ''
      formDetail.value.idCard = ''
      formDetail.value.defaultFlag = 0
      formDetail.value.gender = 0
      // 新增只需要4个属性，id必须删除，写null也不行，后端也会报错
      delete formDetail.value.id
    }
  },
  { deep: true }
)

const emits = defineEmits(['addSuccessEvent'])
const showRight = ref(false)
const fn = () => {
  // console.log('我是父组件的函数')
  showRight.value = false
}

const openPopup = () => {
  showRight.value = true
}

// 保存
const save = () => {
  // 下面这种通过隐藏的按钮，调用他的click方法不行，因为native-type="submit"的按钮，不是普通的按钮，没有click方法， 查看官网发现，van-form表单 内置有 submit方法，等价于native-type="submit"的按钮
  // submitRef.value.click()  // 以前我们人资里面 自己封装上传组件的时候用过这种
  submitRef.value.submit()
}

const onClickButton = () => {
  showConfirmDialog({
    title: '提示',
    message: '是否确定删除改数据？'
  })
    .then(async () => {
      await deletePatientRequest(formDetail.value.id)
      // 删除成功以后，关闭popup弹出层
      showRight.value = false
      // 回到之前列表页面，在发一次列表请求
      emits('addSuccessEvent')
    })
    .catch(() => {
      // on cancel
    })
}

// 表单提交需要的字段，用一个对象包裹起来，方便后续传递值
const formDetail = ref<any>({
  name: '',
  idCard: '',
  defaultFlag: 0, //  0不是默认 1是默认患者
  gender: 0 // 1 男  0 女
})
const pattern = /\d{6}/
const onSubmit = async () => {
  // 在发请求之前，还需要校验一下身份证号和性别是否符合
  const id = formDetail.value.idCard.slice(-2, -1)
  if (
    // 身份证号倒数第二位 是偶数 就是女生。 奇数就是男生， 两个条件
    (id % 2 === 0 && formDetail.value.gender === 0) ||
    (id % 2 === 1 && formDetail.value.gender === 1)
  ) {
    // 在这里区分以下编辑和新增
    if (formDetail.value.id) {
      // 这里就是编辑，发起编辑的请求，下面就是新增
      await updatePatientRequest(formDetail.value)

      // 先点编辑 再点新增，就有bug。 数据残留的bug
      // 编译完毕以后，将id清除掉
      // delete formDetail.value.id
      formDetail.value.id = null
    } else {
      await addPatientRequest(formDetail.value)
    }

    // 添加成功以后，关闭popup弹出层
    showRight.value = false
    // 回到之前列表页面，在发一次列表请求
    emits('addSuccessEvent')
  } else {
    showToast('当前选择的性别和身份证号不一致，请重新填写')
  }
}

// 默认就诊人的计算属性： checkbox组件需要的值是 true或者false； 但是后端需要的值是0 1
// 我们就是用可以修改的计算属性，get函数里面 同0 1 将计算属性改为 true  false
// 在set里面，就是用户点击了checkbox复选框的时候，对计算属性有修改的地方，那么我们就将
// 修改的true 和false，在又反转回 0  1 给后端使用

// 这个默认的业务一定要说清楚 页面上显示的内容true/false，和后端需要的内容0 1
// 核心的做法，就是通过可以修改的计算属性 get，set形式。 将v-model上面绑定一个计算属性
const defaultFlagCom = computed({
  get() {
    return formDetail.value.defaultFlag === 0 ? false : true
  },
  set(val) {
    formDetail.value.defaultFlag = val ? 1 : 0
  }
})
const updateGenderEvent = (e: number) => {
  formDetail.value.gender = e
}

// 正则在工作里面就是百度出来：  js  汉字 正则校验
const patternChinese = /^[\u4e00-\u9fa5]{2,5}$/
// https://xbeginagain.github.io/generator/
// http://id.dcode.top/
// 1-6 省市区
// 7-14 出生年月日
// 15-17 出生区域政府的顺序码    17  奇数是男生  偶数就是女生
// 18 位 是根据前面17位位算出来的 验证码。  有可能是X
// 工作里面，前端一般是用第三方包，去校验身份证， 校验的包要去 npmjs.com官网
// 1. 安装包 pnpm add idcard  2. 改造校验规则，去看vant-ui文档  3. 测试
const patternIdCard =
  /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/
const nameRules = ref<any[]>([
  { required: true, message: '请输入姓名' },
  { pattern: patternChinese, message: '姓名只能输入2-5位' }
])
// https://www.npmjs.com/package/idcard
const validator = (val: any) => {
  console.log(idCard.info(val))
  return idCard.verify(val)
}

const idCardRules = ref<any[]>([
  { required: true, message: '请输入身份证号' },
  { validator, message: '身份证号格式错误' }
  // { pattern: patternIdCard, message: '身份证号格式错误' }
])

// vue3的话，父组件想通过组件实例对象访问子组件的 所有属性和方法
// 需要手动的通过 defineExpose 向外面抛出对应的属性和函数即可
defineExpose({
  openPopup: openPopup
})
</script>

<style lang="scss" scoped>
.patient-detail {
  .van-cell {
    padding-left: 0;
  }
  .default-patient {
    margin-top: 20px;
    display: flex;
    .van-field__label {
      margin-right: 0;
    }
  }
}
</style>
